package com.project.common.filter;

import java.util.ArrayList;
import java.util.List;

public class Criteria {
    private final List<Criterion> criteria;
    private final String connective;

    public Criteria() {
        this(Logic.OR);
    }

    public Criteria(Logic logic) {
        this.connective = logic.getValue();
        this.criteria = new ArrayList<>();
    }


    public boolean isValid() {
        return !criteria.isEmpty();
    }

    public String getConnective() {
        return connective;
    }

    public List<Criterion> getCriteria() {
        return criteria;
    }

    public Criteria addCriterion(Criterion criterion) {
        return this.addCriterion(Logic.AND, criterion);
    }

    public Criteria addCriterion(Logic logic, Criterion criterion) {
        criterion.setConnective(this.criteria.isEmpty() ? Logic.NONE.getValue() : logic.getValue());
        this.criteria.add(criterion);
        return this;
    }

    public Criteria and(Criterion criterion) {
        return this.addCriterion(criterion);
    }

    public Criteria or(Criterion criterion) {
        return this.addCriterion(Logic.OR, criterion);
    }

    public Criteria andIsNull(String column) {
        return and(Criterion.isNull(column));
    }

    public Criteria orIsNull(String column) {
        return or(Criterion.isNull(column));
    }

    public Criteria andNotNull(String column) {
        return and(Criterion.notNull(column));
    }

    public Criteria orNotNull(String column) {
        return or(Criterion.notNull(column));
    }

    public Criteria andEqual(String column, Object value) {
        return and(Criterion.equal(column, value));
    }

    public Criteria orEqual(String column, Object value) {
        return or(Criterion.equal(column, value));
    }

    public Criteria andNotEqual(String column, Object value) {
        return and(Criterion.notEqual(column, value));
    }

    public Criteria orNotEqual(String column, Object value) {
        return or(Criterion.notEqual(column, value));
    }

    public Criteria andLessThan(String column, Object value) {
        return and(Criterion.lessThan(column, value));
    }

    public Criteria orLessThan(String column, Object value) {
        return or(Criterion.lessThan(column, value));
    }

    public Criteria andLessThanOrEqual(String column, Object value) {
        return and(Criterion.lessThanOrEqual(column, value));
    }

    public Criteria orLessThanOrEqual(String column, Object value) {
        return or(Criterion.lessThanOrEqual(column, value));
    }

    public Criteria andGreatThan(String column, Object value) {
        return and(Criterion.greatThan(column, value));
    }

    public Criteria orGreatThan(String column, Object value) {
        return or(Criterion.greatThan(column, value));
    }

    public Criteria andGreatThanOrEqual(String column, Object value) {
        return and(Criterion.greatThanOrEqual(column, value));
    }

    public Criteria orGreatThanOrEqual(String column, Object value) {
        return or(Criterion.greatThanOrEqual(column, value));
    }

    public Criteria andStartWith(String column, String value) {
        return and(Criterion.startWith(column, value));
    }

    public Criteria orStartWith(String column, String value) {
        return or(Criterion.startWith(column, value));
    }

    public Criteria andNotStartWith(String column, String value) {
        return and(Criterion.notStartWith(column, value));
    }

    public Criteria orNotStartWith(String column, String value) {
        return or(Criterion.notStartWith(column, value));
    }

    public Criteria andEndWith(String column, String value) {
        return and(Criterion.endWith(column, value));
    }

    public Criteria orEndWith(String column, String value) {
        return or(Criterion.endWith(column, value));
    }

    public Criteria andNotEndWith(String column, String value) {
        return and(Criterion.notEndWith(column, value));
    }

    public Criteria orNotEndWith(String column, String value) {
        return or(Criterion.notEndWith(column, value));
    }

    public Criteria andContains(String column, Object value) {
        return and(Criterion.contains(column, value));
    }

    public Criteria orContains(String column, Object value) {
        return or(Criterion.contains(column, value));
    }

    public Criteria andNotContains(String column, Object value) {
        return and(Criterion.notContains(column, value));
    }

    public Criteria orNotContains(String column, Object value) {
        return or(Criterion.notContains(column, value));
    }

    public Criteria andIn(String column, Object value) {
        return and(Criterion.in(column, value));
    }

    public Criteria orIn(String column, Object value) {
        return or(Criterion.in(column, value));
    }

    public Criteria andNotIn(String column, Object value) {
        return and(Criterion.notIn(column, value));
    }

    public Criteria orNotIn(String column, Object value) {
        return or(Criterion.notIn(column, value));
    }

    public Criteria andBetween(String column, Object value, Object nextValue) {
        return and(Criterion.between(column, value, nextValue));
    }

    public Criteria orBetween(String column, Object value, Object nextValue) {
        return or(Criterion.between(column, value, nextValue));
    }

    public Criteria andNotBetween(String column, Object value, Object nextValue) {
        return and(Criterion.notBetween(column, value, nextValue));
    }

    public Criteria orNotBetween(String column, Object value, Object nextValue) {
        return or(Criterion.notBetween(column, value, nextValue));
    }
}
